package com.sd365.permission.centre.api.controller;

import com.sd365.common.log.api.annotation.ApiLog;
import com.sd365.common.util.BeanUtil;
import com.sd365.permission.centre.api.JobApi;
import com.sd365.permission.centre.pojo.dto.JobDTO;
import com.sd365.permission.centre.pojo.query.JobQuery;
import com.sd365.permission.centre.pojo.vo.JobVO;
import com.sd365.permission.centre.service.JobManageService;
import com.sd365.permission.centre.service.job.utils.CronUtil;
import com.sd365.permission.centre.service.job.utils.QuartzUtils;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;

@Slf4j
@RestController
public class JobManageController implements JobApi{
    @Resource
    JobManageService jobManageService;
    @Autowired
    private Scheduler scheduler;
    @Autowired
    private CronUtil cronUtil;
    /**
     * 查询任务信息，分页
     * @param jobQuery
     * @return
     */
    @ApiLog
    @Override
    public List<JobVO> commonQueryJob(JobQuery jobQuery){
        List<JobDTO> jobs = jobManageService.commonQueryJob(jobQuery);
        List<JobVO> jobVOS = BeanUtil.copyList(jobs, JobVO.class);
        for (int i = 0; i < jobVOS.size(); i++) {
            if(jobVOS.get(i).getStatus()==1){
            jobVOS.get(i).setLastRunTime(new Date(cronUtil.getLastTriggerTime(jobVOS.get(i).getCron())));
            jobVOS.get(i).setNextRunTime(new Date(cronUtil.getNextTriggerTime(jobVOS.get(i).getCron())));
            }
        }
        return jobVOS;
    }


    /**
     * 增加任务，默认状态值为1，新增即启动
     * @param jobDTO
     * @return
     */
    @ApiLog
    @Override
    public Boolean add(@Valid JobDTO jobDTO) {
        try {
            //执行调度
            QuartzUtils.createScheduleJob(scheduler,jobDTO);
            log.info("任务执行"+jobDTO.getJobName());
            //基础数据写入数据库
            jobManageService.add(jobDTO);
            log.info("计划创建"+jobDTO.getJobName());
        }catch (Exception e){
            log.info("调度错误"+jobDTO.getJobName());
            return false;
        }
        return true;
    }

    /**
     * 删除任务
     * @param id
     * @return
     */
    @ApiLog
    @Override
    public Boolean remove(Long id,Long version,String jobName) {
        try {
            //删除任务
            QuartzUtils.deleteScheduleJob(scheduler,jobName);
            log.info("任务停止"+jobName);
            //删除数据记录
            jobManageService.remove(id,version);
            log.info("计划移除"+jobName);
        }catch (Exception e){
            log.info("调度错误"+jobName);
            return false;
        }
        return true;
    }

    /**
     * 编辑任务
     * @param jobDTO
     * @return
     */
    @ApiLog
    @Override
    public Boolean modify(@Valid JobDTO jobDTO) {
        try {
            //更新任务
            QuartzUtils.updateScheduleJob(scheduler,jobDTO);
            log.info("任务执行"+jobDTO.getJobName());
            //更新数据库
            return jobManageService.modify(jobDTO);
        }catch (Exception e){
            log.info("调度错误"+jobDTO.getJobName());
        }
        return true;
    }
    @ApiLog
    @Override
    public Boolean pauseJob(@Valid JobDTO jobDTO) {
        try {
            //停止任务
            QuartzUtils.pauseScheduleJob(scheduler,jobDTO.getJobName());
            log.info("任务停止"+jobDTO.getJobName());
            //更新任务状态
            jobManageService.pauseJobStatus(jobDTO.getId());
            log.info("计划暂停"+jobDTO.getJobName());
        }catch (Exception e){
            log.info("暂停失败"+jobDTO.getJobName());
            return false;
        }
        return true;
    }

    /**
     * 启动时根据错误策略执行相应操作
     * @param jobDTO
     * @return
     */
    @ApiLog
    @Override
    public Boolean resume(@Valid JobDTO jobDTO) {
        try {
            QuartzUtils.resumeScheduleJob(scheduler,jobDTO.getJobName());
            log.info("任务执行"+jobDTO.getJobName());
            jobManageService.resumeJobStatus(jobDTO.getId());
            log.info("计划恢复"+jobDTO.getJobName());
        }catch (Exception e){
            log.info("调度错误"+jobDTO.getJobName());
            if(jobDTO.getErrorTactics()==1){
                try {
                    QuartzUtils.runOnce(scheduler,jobDTO.getJobName());
                    log.info("任务执行"+jobDTO.getJobName());
                    jobManageService.resumeJobStatus(jobDTO.getId());
                    log.info("计划恢复"+jobDTO.getJobName());
                }catch (Exception et){
                    log.info("调度再次错误"+jobDTO.getJobName());
                    return false;
                }
            }else{
                try {
                    QuartzUtils.resumeScheduleJob(scheduler,jobDTO.getJobName());
                    log.info("任务执行"+jobDTO.getJobName());
                    jobManageService.resumeJobStatus(jobDTO.getId());
                    log.info("计划恢复"+jobDTO.getJobName());
                }catch (Exception et){
                    log.info("调度再次错误"+jobDTO.getJobName());
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 立即执行一次任务,失败后根据错误策略执行
     * @param jobDTO
     * @return
     */
    @ApiLog
    @Override
    public Boolean runOnce(@Valid JobDTO jobDTO) {
        try {
            QuartzUtils.runOnce(scheduler,jobDTO.getJobName());
            log.info("任务执行"+jobDTO.getJobName());
            jobManageService.resumeJobStatus(jobDTO.getId());
            log.info("计划恢复"+jobDTO.getJobName());
        }catch (Exception e){
            log.info("调度错误"+jobDTO.getJobName());
            if(jobDTO.getErrorTactics()==1){
                try {
                    QuartzUtils.runOnce(scheduler,jobDTO.getJobName());
                    log.info("任务执行"+jobDTO.getJobName());
                    jobManageService.resumeJobStatus(jobDTO.getId());
                    log.info("计划恢复"+jobDTO.getJobName());
                }catch (Exception et){
                    log.info("调度再次错误"+jobDTO.getJobName());
                    return false;
                }
            }else{
                try {
                    QuartzUtils.resumeScheduleJob(scheduler,jobDTO.getJobName());
                    log.info("任务执行"+jobDTO.getJobName());
                    jobManageService.resumeJobStatus(jobDTO.getId());
                    log.info("计划恢复"+jobDTO.getJobName());
                }catch (Exception et){
                    log.info("调度再次错误"+jobDTO.getJobName());
                    return false;
                }
            }
        }
        return true;
    }
}
